﻿using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Threading;
using System.Web.Script.Serialization;

namespace MapleLeaf.Client {
    public class Patcher {
        public int RetryTimes { get; }

        public static Uri PatchServer {
            get {
                if (_PatchServer == null) {
                    try {
                        Uri uri = new Uri("http://res.hongsh.net");
                        if (Dns.GetHostEntry(uri.Host).AddressList.Length != 0) {
                            _PatchServer = uri;
                        }
                    }
                    catch {
                    }
                }
                if (_PatchServer == null) {
                    _PatchServer = new Uri("http://192.144.172.75");
                }
                return _PatchServer;
            }
        }

        // Token: 0x0600002D RID: 45 RVA: 0x000030B8 File Offset: 0x000012B8
        public bool CheckPatch(PatchContext ctx) {
            ctx.Message = "获取更新列表中";
            try {
                Uri requestUri = new Uri(PatchServer, string.Format("/@list/{0}?fields=name,size,md5", ctx.ProductName));
                WebRequest webRequest = WebRequest.Create(requestUri);
                webRequest.Proxy = null;
                webRequest.Timeout = 5000;
                WebResponse response = webRequest.GetResponse();
                Stream responseStream = response.GetResponseStream();
                string input = new StreamReader(responseStream).ReadToEnd();
                string[][] array = new JavaScriptSerializer().Deserialize<string[][]>(input);
                foreach (string[] array3 in array) {
                    PatchInfo patchInfo = new PatchInfo {
                        Name = array3[0],
                        Size = int.Parse(array3[1]),
                        Md5 = array3[2]
                    };
                    if (!patchInfo.Name.EndsWith(PatchSuffix, StringComparison.OrdinalIgnoreCase)) {
                        FileInfo fileInfo = new FileInfo(patchInfo.Name);
                        if (!fileInfo.Exists || fileInfo.Length != patchInfo.Size || GetFileMd5(fileInfo) != patchInfo.Md5) {
                            ctx.PatchList.Add(patchInfo);
                            ctx.PatchLength += patchInfo.Size;
                        }
                    }
                }
            }
            catch (Exception ex) {
                ctx.Message = ex.Message;
                return false;
            }
            ctx.Message = "已获取更新列表";
            return ctx.PatchList.Count > 0;
        }

        // Token: 0x0600002E RID: 46 RVA: 0x0000324C File Offset: 0x0000144C
        public bool Download(PatchContext ctx) {
            try {
                ctx.Message = "开始下载更新";
                byte[] array = new byte[64];
                foreach (PatchInfo patchInfo in ctx.PatchList) {
                    ctx.Message = patchInfo.Name;
                    FileInfo fileInfo = new FileInfo(patchInfo.Name + PatchSuffix);
                    if (!fileInfo.Exists || fileInfo.Length != patchInfo.Size || GetFileMd5(fileInfo) != patchInfo.Md5) {
                        using (FileStream fileStream = fileInfo.Open(FileMode.Create, FileAccess.ReadWrite)) {
                            int i = 0;
                            Uri requestUri = new Uri(PatchServer, ctx.ProductName + "/" + patchInfo.Name);
                            WebRequest webRequest = WebRequest.Create(requestUri);
                            WebResponse response = webRequest.GetResponse();
                            using (Stream responseStream = response.GetResponseStream()) {
                                while (i < patchInfo.Size) {
                                    int num = responseStream.Read(array, 0, array.Length);
                                    fileStream.Write(array, 0, num);
                                    i += num;
                                    ctx.PatchedLength += num;
                                }
                            }
                            continue;
                        }
                    }
                    ctx.PatchedLength += patchInfo.Size;
                }
                ctx.Message = "更新下载完成";
            }
            catch (Exception ex) {
                ctx.Message = ex.Message;
                return false;
            }
            return true;
        }

        // Token: 0x0600002F RID: 47 RVA: 0x00003434 File Offset: 0x00001634
        public static void Patch(PatchContext ctx) {
            bool flag = false;
            if (ctx.PatchList.Count > 0) {
                try {
                    foreach (PatchInfo patchInfo in ctx.PatchList) {
                        string fullPath = Path.GetFullPath(patchInfo.Name);
                        if (App.FileInfo.FullName.Equals(Path.GetFullPath(patchInfo.Name), StringComparison.OrdinalIgnoreCase)) {
                            flag = true;
                        }
                        else {
                            for (int i = 0; i < 10; i++) {
                                try {
                                    if (File.Exists(fullPath)) {
                                        File.SetAttributes(fullPath, FileAttributes.Normal);
                                        File.Delete(fullPath);
                                    }
                                    File.Move(fullPath + PatchSuffix, fullPath);
                                    break;
                                }
                                catch {
                                    Thread.Sleep(500);
                                }
                            }
                        }
                    }
                }
                catch {
                }
            }
            if (flag) {
                WinExec(App.FileInfo.FullName + PatchSuffix, 5U);
            }
            else {
                Process.Start(App.FileInfo.FullName);
            }
            Environment.Exit(0);
        }


        private static string GetFileMd5(FileInfo info) {
            FileStream fileStream = info.Open(FileMode.Open, FileAccess.Read, FileShare.Read);
            string result = BitConverter.ToString(MD5.Create().ComputeHash(fileStream)).Replace("-", null).ToLower();
            fileStream.Close();
            return result;
        }

        [DllImport("kernel32.dll")]
        public static extern uint WinExec(string lpCmdLine, uint uCmdShow = 5U);


        public Patcher() {
            //Class8.k7EOLlbzbnCJj();
            RetryTimes = 5;
            //base..ctor();
        }

        static Patcher() {
            //Class8.k7EOLlbzbnCJj();
            PatchSuffix = ".patching";
        }

        public static readonly string PatchSuffix;


        private static Uri _PatchServer;

    }
}
